package com.cskaoyan.javase.oop1._16access._3why;
/**
 * 给类或者类中结构加上访问权限，就相当于给房子加锁，没有钥匙（没有访问权限）就进不去（访问不到）
 * 但以上说的是正常情况
 * 房子的锁是可以撬开，是可以强行打破的，同样的访问权限符也不是绝对不可破解的。
 * 比如Java自身就提供了反射的特性，反射是可以破解访问权限的。
 * 在反射面前,任何私有都是没有作用的
 *
 * 那么就像给门加锁，是警告你不能逾越界限，否则就是违法操作一样。
 * 访问权限的使用，最基本的，自然是用来控制访问权限的（这是废话）。
 * 但也隐含了警告和暗示的作用：
 * 告诉代码的使用者，哪些地方不要触碰，哪些地方应该使用。起到警告、约束和指导代码使用者的功能。
 *      专门提供给外界使用的，推荐使用的，用public。告诉别人：这里是你需要关注、了解和使用的地方。
 *      所有明确提供给外界使用，实现功能的方法，需要用public修饰。
 *      外界不应该触碰的地方，用私有private修饰，告诉别人：这里你不需要你看，也不需要你管
 * 以上说的有点抽象,我们具体举一些案例:
 * 具体的案例是：
 *      1.工具类，既然所有的方法，都可以直接用"类名."去调用，不需要创建对象！
 *          既然不需要对象，那就干脆不要创建对象，直接把这个功能去掉！
 *          Java中的所有工具类，都应该私有化无参构造方法！！
 *          对于工具类来说,这一步是必不可少的
 *
 *      2.类中需要提供给外界使用的方法的实现过程中，经常需要一些"中间的过程"方法。
 *          这些方法不需要提供给外界使用，仅作为内部实现功能使用。
 *          注意: 所有类中的"中间方法"都应该私有化它们！
 *
 *      3.工厂设计模式。
 *          指的是不通过自身构造器创建对象，而是通过"工厂"去创建对象，这时类的构造器应该私有。
 *          由于我们知识技能有限，暂时还不能实现工厂设计模式。不用着急，后期我们会学习。
 *
 * 以上,三种实际场景,我们可以得到什么结论?或者说,合理的使用访问权限修饰符,有什么好处?
 *
 * 如果你能够严格按照上述描述使用访问权限修饰符，那么好处是显而易见的：
 *      把代码的开发者和代码的使用者给区分开来了：
 *      1.代码使用者无需关心没有访问权限的代码，仅需要关心具有访问权限的部分就可以了。
 *          私有或者没有访问权限的部分，既然不让我看，不让我用，那我就老老实实不看，不用。
 *          实际上，当你去使用别人的代码时，你也不希望需要完全读懂所有代码，才能够使用吧？
 *
 *      2.代码开发者，可以自由的开发，对外界没有访问权限部分的代码。
 *          这些私有的，或者对外界不可见部分的代码，叫做隐藏代码的具体实现细节，可以很方便的修改代码实现。
 *          想一想，如果一个方法是public修饰的，在外界多处被使用，你敢随便就动这个方法代码吗？
 *
 * 总之,合理的使用访问权限修饰符,对大家都有好处.
 * 所以，我们就可以总结出，我们在实际开发中，使用类中结构的访问权限修饰符的原则：
 *      1.尽量私有化，方便自己修改代码，隐藏实现细节。
 *      2.如果不能私有化，那也应该尽量少的给予访问权限，先从默认权限开始考虑。
 *      3.只有确定这个结构，一定需要在外部（尤其是不同包下）被访问时，才考虑给public，尽量少给public。
 * 权限这个东西，要吝啬，不要"大方"！
 *
 *
 * @since 16:55
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
}
// 这是一个工具类案例
class UtilsDemo{
    // 既然是工具类应该私有化构造器
    private UtilsDemo() {
    }

    // test方法需要提供给外界使用,外界需要关注这个方法,所以public修饰它
    public static void test(){
        System.out.println("hello");
        System.out.println("hello");
        // 中间需要一个过程方法,来完成test方法的功能
        test2();
        System.out.println("hello");
    }

    // test2方法是一个中间过程方法,外界不需要关心它,应该私有化它
    // Access can be private
    private static void test2() {
        System.out.println("实现test方法功能的过程方法");
    }
}

class Student{
    // 希望工厂创建它的对象,所以应该私有化构造器,避免被new对象
    private Student(){}
}